策略模式定義一個演算法介面,並讓客戶端在執行時期根據需求替換具體實作。
不知道大家平常都怎麼上班呢?大多時候我會騎機車,想要放鬆一點的時候會改搭公車。如果要到分公司開會的話,因為距離較遠,則會改搭捷運。雖然這三種交通工具不同,但都能讓我順利抵達公司,我可以根據每天的心情與情境選擇最合適的交通工具。
其實,這樣的選擇就像是策略模式中的策略選擇一樣。策略模式提供了多種達成同一目標的手段,而這些手段各有優缺點。我選擇不同的交通工具,就像是選擇不同的策略來完成「上班」這個任務。不論我選擇哪一種交通工具,最終都能順利抵達公司。
假設我們要開發一款翻譯工具,這款工具以 Google 翻譯作為預設的翻譯引擎,並提供 ChatGPT 與 Aya23 等生成式 AI 作為進階選項。我們可以透過策略模式定義不同的翻譯策略,再讓使用者自行選擇喜歡的翻譯方式。
定義通用的翻譯策略界面。
interface TranslationStrategy {
translate(input: string): void;
}
定義具體的翻譯策略。
class GoogleTranslateStrategy implements TranslationStrategy {
translate(input: string) {
console.log(`Translate '${input}' with Google Translate`);
}
}
class ChatGPTStrategy implements TranslationStrategy {
translate(input: string) {
console.log(`Translate '${input}' with Chat GPT`);
}
}
class Aya23Strategy implements TranslationStrategy {
translate(input: string) {
console.log(`Translate '${input}' with Aya 23`);
}
}
讓使用者透過 setStrategy
指定翻譯策略。
class Translator {
private targetLanguage: string = "zh-TW";
private strategy: TranslationStrategy = new GoogleTranslateStrategy();
translate(input: string) {
this.strategy.translate(input);
}
setStrategy(strategy: TranslationStrategy) {
this.strategy = strategy;
}
}
class TranslatorTestDrive {
static main() {
const translator = new Translator();
const chatGPTStrategy = new ChatGPTStrategy();
const aya23Strategy = new Aya23Strategy();
translator.translate("Hello World");
translator.setStrategy(chatGPTStrategy);
translator.translate("Hello World");
translator.setStrategy(aya23Strategy);
translator.translate("Hello World");
}
}
如此一來,我們可以輕鬆地切換翻譯工具的翻譯引擎,而不需修改既有的程式碼。我們也能添加或移除翻譯策略以支援不同的翻譯選項,其他服務也能方便地使用這些翻譯策略。
策略模式中包含兩種角色:
策略模式定義了一個演算法介面,並讓不同的演算法實現這個介面,從而統一各種演算法的實作。客戶端只需依賴這個介面,而不必依賴於具體的實作,這使得使用者可以輕鬆地通過改變策略來更改程式邏輯。
此外,策略模式將程式邏輯提取到獨立的類別中,這讓同樣的程式可以方便地被不同的客戶端重複使用。